/* $Id:record.cc $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#include <sstream>
#include <fstream>
#include "../general/util.h"
#include "record.h"
#include "../general/general.h"

record::record() {
    name="";
    fields=map<string,class field>();
    maxFields=0;
    relations=false;
    main=true;
    named=false;
    ordered=false;
    idField="";
}

// Field : name

const string record::getName() const { return name; }
void record::setName(const string v) { name=v; }

// Field : fields

class field& record::getFields(const string v) { return fields[v]; }
list<class field>& record::listFields() {
    static list<class field> res;
    res.clear();
    loopMap(fields,v,class field) {
        res.push_back(*v);
    }
    res.sort();
    return res;
}
void record::setFields(class field &v) {
    if (v.getNr()==0) v.setNr(++maxFields);
    if (v.getName()=="") throw unnamed();
    if (v.getAbbreviation()=="") {
        int found=true;
        for(int i=1; found && i<3; i++) {
            found=false;
            loopRecordFields(this,fld) {
                if (fld->getAbbreviation()==v.getName().substr(0,i)) found=true;
            }
            if (!found) v.setAbbreviation(v.getName().substr(0,i));
        }
        if (found) v.setAbbreviation(v.getName().substr(0,2)+tostr(v.getNr()));
    }
    fields[v.getName()]=v;
}
void record::delFields(const string v) { fields.erase(v); }
const bool record::isFields(const string v) const { return fields.count(v)>0; }

// Field : relations

const bool record::getRelations() const { return relations; }
void record::setRelations(const bool v) { relations=v; }

// Field : main

const bool record::getMain() const { return main; }
void record::setMain(const bool v) { main=v; }

// Field : named

const bool record::getNamed() const { return named; }
void record::setNamed(const bool v) { named=v; }

// Field : ordered

const bool record::getOrdered() const { return ordered; }
void record::setOrdered(const bool v) { ordered=v; }

// Field : idField

const string record::getIdField() const { return idField; }
void record::setIdField(const string v) { idField=v; }

void record::xml(ofstream &f, int l, int r) {
    f << ncpy(l, "  ") << "<record name=\"" << getName() <<
    "\" relations=\"" << (getRelations()?"true":"false") <<
    "\" main=\"" << (getMain()?"true":"false") <<
    "\" named=\"" << (getNamed()?"true":"false") <<
    "\" ordered=\"" << (getOrdered()?"true":"false") <<
    "\" idField=\"" << getIdField() <<
    "\">" << endl;
    if (r==0) {
        loopRecordFields(this, s_fields) {
            s_fields->xml(f,l+1);
        }
    }
    f << ncpy(l, "  ") << "</record>" << endl;
}

// Repository

recordRepository record_repo;

class record& recordRepository::getRecord(const string v) { return records[v]; }
void recordRepository::setRecord(class record& v) {
    if (v.getName()=="") throw unnamed();
    records[v.getName()]=v;
}
map<string,class record>& recordRepository::listRecord() { return records; }
void recordRepository::delRecord(const string v) { records.erase(v); }
const bool recordRepository::isRecord(const string v) const { return records.count(v)>0; }
